package com.pujiewang.gateway.util;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferFactory;
import org.springframework.http.HttpStatusCode;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.net.*;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

/**
 * @author renminghe
 * @ClassName NetUtil
 * @Description 网络工具
 * @CreateTime 2022-11-07 17:18
 */
public class NetUtil {
    private static final Logger logger = LoggerFactory.getLogger(NetUtil.class);
    private static final ObjectMapper objectMapper = new ObjectMapper();

    /**
     * 获取远程访问IP
     * @param request 请求体
     * @return 请求地址Ip
     */
    public static String getRemoteHost(ServerHttpRequest request) {
        String ip = getHeader(request, "x-forwarded-for");
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = getHeader(request,"Proxy-Client-IP");
        }
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = getHeader(request,"WL-Proxy-Client-IP");
        }
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = Optional.ofNullable(request.getRemoteAddress().getAddress().getHostAddress()).orElse("");
        }
        return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : ip;
    }

    // 获取最后一个ip地址（可能有多个ip）
    public static long getHostIP() throws SocketException {

        Enumeration<NetworkInterface> allNetInterfaces;
        byte resultIP = 0;

        allNetInterfaces = NetworkInterface.getNetworkInterfaces();

        InetAddress ip;
        while (allNetInterfaces.hasMoreElements()) {
            NetworkInterface netInterface = allNetInterfaces.nextElement();
            Enumeration<InetAddress> addresses = netInterface.getInetAddresses();
            while (addresses.hasMoreElements()) {
                ip = addresses.nextElement();
                if (ip instanceof Inet4Address && !ip.getHostAddress().equals("127.0.0.1")) {
                    byte[] address = ip.getAddress();
                    resultIP = address[address.length - 1];

                    return resultIP < 0 ? (256 + resultIP) : resultIP;
                }
            }

        }
        return resultIP;

    }

    public static String getLocalIpAddress(){
        InetAddress ip;      //用于获取IP(因为是静态的所以不需要使用new来实例化
        String IP = null;    //用于返回IP
        try {
            ip = Inet4Address.getLocalHost();    //获取IP
            IP = ip.getHostAddress();        	//以字符串形式存储IP
        } catch (UnknownHostException e) {
            logger.error("UnknownHostException, ", e);
        }
        return IP;
    }

    /**
     * 获取请求头
     * @param request 请求体
     * @param headerName header名字
     * @return 请求头
     */
    public static String getHeader(ServerHttpRequest request, String headerName) {
        return getHeaderUnlessDefaultValue(request, headerName, null);
    }

    /**
     * 获取请求头，如果没有设置默认值
     * @param request 请求体
     * @param headerName header名字
     * @param defaultValue 默认值
     * @return 请求头
     */
    public static String getHeaderUnlessDefaultValue(ServerHttpRequest request, String headerName, String defaultValue) {
        return Optional
                .ofNullable(request.getHeaders().getFirst(headerName))
                .orElse(defaultValue);
    }

    /**
     * 构建自定义响应体
     * @param exchange ServerWebExchange
     * @param message 消息
     * @param status 状态码
     * @return 消息返回体
     */
    public static Mono<Void> buildResponse(ServerWebExchange exchange, String message, HttpStatusCode status) {

        Map<String, Object> responseBody = new HashMap<>();
        responseBody.put("message", message);
        responseBody.put("status", status.value());
        responseBody.put("result", null);
        responseBody.put("timestamp", System.currentTimeMillis());

        // 将响应体转换为字节数组
        ServerHttpResponse response = exchange.getResponse();
        response.setStatusCode(status);
        response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
        DataBufferFactory bufferFactory = response.bufferFactory();
        try {
            byte[] bytes = objectMapper.writeValueAsBytes(responseBody);
            DataBuffer buffer = bufferFactory.wrap(bytes);
            return response.writeWith(Mono.just(buffer));
        } catch (Exception e) {
            logger.error("Failed to write error response", e);
            return Mono.error(e);
        }
    }

}
